
import java.io.{FileInputStream, FileOutputStream, ObjectInputStream, ObjectOutputStream}
import java.text.SimpleDateFormat
import java.util.Date
import scala.collection.mutable.ListBuffer

case class MemberCard(val cardNo: String, var name: String, var password: String, var points: Int, val registrationDate: String) extends Serializable

class SuperMarket(val name: String, val address: String, val phone: String) extends Serializable {
  private var members = ListBuffer[MemberCard]()

  def addMember(name: String, password: String): MemberCard = {
    val cardNo = generateCardNo()
    val registrationDate = new SimpleDateFormat("yyyy-MM-dd").format(new Date())
    val newMember = MemberCard(cardNo, name, password, 100, registrationDate)
    members += newMember
    newMember
  }

  def findMember(cardNo: String, password: String): Option[MemberCard] = {
    members.find(m => m.cardNo == cardNo && m.password == password)
  }

  def accumulatePoints(cardNo: String, password: String, amount: Int): Boolean = {
    findMember(cardNo, password) match {
      case Some(member) =>
        member.points += amount
        true
      case None => false
    }
  }

  def queryPoints(cardNo: String, password: String): Option[MemberCard] = {
    findMember(cardNo, password)
  }

  def changePassword(cardNo: String, password: String, newPassword: String): Boolean = {
    findMember(cardNo, password) match {
      case Some(member) =>
        member.password = newPassword
        true
      case None => false
    }
  }

  def exchangePoints(cardNo: String, password: String, option: Int): Boolean = {
    findMember(cardNo, password) match {
      case Some(member) =>
        option match {
          case 1 if member.points >= 300 =>
            member.points -= 300
            true
          case 2 if member.points >= 500 =>
            member.points -= 500
            true
          case 3 if member.points >= 1000 =>
            member.points -= 1000
            true
          case _ => false
        }
      case None => false
    }
  }

  private def generateCardNo(): String = {
    import scala.util.Random
    Random.alphanumeric.take(8).mkString
  }
}

object SuperMarket {
  def main(args: Array[String]): Unit = {
    var sp = loadSuperMarket()
    while (true) {
      println("*************************欢迎进入超市会员管理系统*************************")
      println("1、累计积分  2、兑换积分  3、查询剩余积分  4、修改密码  5、开卡  6、退出")
      println("**********************************************************************")
      print("请选择：")
      val choice = scala.io.StdIn.readInt()
      choice match {
        case 1 =>
          print("请输入您的会员卡号：")
          val cardNo1 = scala.io.StdIn.readLine()
          print("请输入您的会员卡密码：")
          val password1 = scala.io.StdIn.readLine()
          print("请输入您此次消费金额（消费1元累计1积分）：")
          val amount = scala.io.StdIn.readInt()
          if (sp.accumulatePoints(cardNo1, password1, amount)) {
            println("累计积分成功！")
          } else {
            println("卡号或密码错误！")
          }
        case 2 =>
          print("请输入您的会员卡号：")
          val cardNo2 = scala.io.StdIn.readLine()
          print("请输入您的会员卡密码：")
          val password2 = scala.io.StdIn.readLine()
          println("1：300积分 兑换一个水杯")
          println("2：500积分 兑换一个棉被")
          println("3：1000积分 兑换一个银镯子")
          print("请选择：")
          val option = scala.io.StdIn.readInt()
          if (sp.exchangePoints(cardNo2, password2, option)) {
            println("兑换成功！")
          } else {
            println("卡号或密码错误，或者积分不足！")
          }
        case 3 =>
          print("请输入您的会员卡号：")
          val cardNo3 = scala.io.StdIn.readLine()
          print("请输入您的会员卡密码：")
          val password3 = scala.io.StdIn.readLine()
          sp.queryPoints(cardNo3, password3) match {
            case Some(member) =>
              println("姓名        会员卡号        剩余积分        开卡日期")
              println(s"${member.name}       ${member.cardNo}          ${member.points}          ${member.registrationDate}")
            case None =>
              println("卡号或密码错误！")
          }
        case 4 =>
          print("请输入您的会员卡号：")
          val cardNo4 = scala.io.StdIn.readLine()
          print("请输入您的会员卡密码：")
          val password4 = scala.io.StdIn.readLine()
          print("请输入新的会员密码：")
          val newPassword = scala.io.StdIn.readLine()
          if (sp.changePassword(cardNo4, password4, newPassword)) {
            println("修改密码成功！")
          } else {
            println("卡号或密码错误！")
          }
        case 5 =>
          print("请输入注册姓名：")
          val name = scala.io.StdIn.readLine()
          var password = ""
          do {
            print("请输入注册密码：")
            password = scala.io.StdIn.readLine()
            if (password.length < 6) {
              println("会员密码不能小于6位，请重新输入注册密码：")
            }
          } while (password.length < 6)
          val newMember = sp.addMember(name, password)
          println(s"恭喜，开通会员卡成功，系统赠送您100积分！您的会员卡号为：${newMember.cardNo}")
        case 6 =>
          saveSuperMarket(sp)
          println("退出系统，再见！")
          return
        case _ =>
          println("无效的选择，请重新输入！")
      }
    }
  }

  def loadSuperMarket(): SuperMarket = {
    try {
      val oin = new ObjectInputStream(new FileInputStream("sp.obj"))
      val obj = oin.readObject()
      oin.close()
      obj.asInstanceOf[SuperMarket]
    } catch {
      case _: Exception =>
        new SuperMarket("合家福", "合肥市某街道", "1939333")
    }
  }

  def saveSuperMarket(sp: SuperMarket): Unit = {
    val oout = new ObjectOutputStream(new FileOutputStream("sp.obj"))
    oout.writeObject(sp)
    oout.close()
  }
}    